home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 1 / ETO Development Tools 1.iso / Essentials / C++ AppleLink Messages / CPlus.Dev$ 5⁄4⁄90 / 0118-Re 2-Value Parameter-Apr90 < prev    next >
Encoding:
Text File  |  1990-05-04  |  3.0 KB  |  75 lines  |  [TEXT/GEOL]

  1. Item    1993529                         29-April-90        16:52PDT
  2.  
  3. From:   D3632                           Cadence Design, Ken Friedenbach,PRT
  4.  
  5. To:     DEREK                           White, Derek
  6.         MIKE.VILOT                      ObjectWare, Michael Vilot,PRT
  7.         D0532                           Aidea Systems, Don Park,PRT
  8.  
  9. cc:     CPLUS.APPLE$                    C++ Interest List--Apple Employees
  10.         CPLUS.DEV$                      C++ Interest List--Developers
  11.  
  12. Sub:    RE 2-Value Parameters
  13.  
  14. Dear Derek, Mike, Don,
  15.  
  16. The problem that Derek points out is an optimization problem, but not a
  17. correctness problem.  The call is being made as a virtual function call, even
  18. though it could be staticly bound at compile time.  But with either calling
  19. mechanism, the semantics will be the same: TShape::Draw() will be called.  So
  20. CFront is not the world's greatest optimizing compiler!  What else is new?  We
  21. should be thankful that is (close?) to being correct!
  22.  
  23. The actual parameter value is used to initialize the formal parameter copy.
  24. The compiler will use the construtor:
  25.         TShape::TShape(const TShape&)
  26. to do the initialization.  If the user does not define this constructor, the
  27. compiler will construct one.  (Why?  Because C supported initialization and
  28. assignment as built-ins.)
  29.  
  30.  
  31. Don's comments addressed the way in which the pointer to the vtable for
  32. TShape:: is used to initialize the copy.  It is correct, and important, to use
  33. the vtable for TShape::, not the vtable for the actual parameter.  If the
  34. vtable of the actual parameter type was used (say TRoundRect) then code that is
  35. called would end up addressing data that is not part of TShape (say the
  36. ovalWidth and ovalHeight fields, which control the "rounding" of the corners).
  37. Multiple inheritance would present a similiar class of problems.
  38.  
  39. So passing by value (which is part of C) is mutually exclusive with
  40. polymorphism.  The "types" still match, but the value is being "narrowed" back
  41. to a true TShape (just as an int will be narrowed to a short or char).  This
  42. "narrowing" must include going back to the virtual functions for the base
  43. class, since it is a base class (sized) object which is being passed.
  44.  
  45.  
  46. Mike's comments about using references are correct.  Polymorphism in C++ is
  47. limited to pointers and references.  (That is why "this" is of type X* rather
  48. than X.)  The choice between pointer and reference is a tough one.  References
  49. are clearly necessary for operators such as =, and += to be defined for user
  50. defined types, since we want to write:
  51.     x = y = z;
  52. not
  53.     &x = &y = z;
  54. which we would have to do for global operators which take pointers.
  55.  
  56.  
  57. Note:  There are some disadvantages in associating polymorphism with pointers.
  58. In C, pointer arithmetic is defined:
  59.     TAType * P = AArray[0];
  60.     ...
  61.     P++;        // next element
  62.     P += 10;    // move 10 elements in array
  63. However, what does this mean:
  64.     TShape * S;
  65.         // S is used as a "polymorphic" pointer
  66.     S++;        // probably a bug!
  67.     S+=3;       // ditto
  68.  
  69.  
  70. Virtually yours,
  71.  
  72. Ken
  73.  
  74.  
  75.